package com.android.microweather;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;

public class CityListActivity extends ListActivity {
	public static final String	CLICK_POSITION = "CityList_click_position";
	
	private static final int	DIALOG_PROGRESSBAR = 1;
	private static final int	DIALOG_UPDATE_NEEDED = 2;
	
	private int 				lastSelectedItemPosition;
	private boolean				openAfterUpdate = false;
	
	Handler updateHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			setListAdapter(getListAdapter());	// update model
			dismissDialog(DIALOG_PROGRESSBAR);
			if (openAfterUpdate) {
				openAfterUpdate = false;
				showCityForecast(lastSelectedItemPosition);
			}
		}
		
	};
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        DataModel model = DataModel.createInstance(this);
        // DEBUG only!!!
        //model.removeAll();
        // DEBUG only!!!
        ArrayList<City> cityList = model.getCityList();
        CityListAdapter cityListAdapter = new CityListAdapter(this, cityList);
        setListAdapter(cityListAdapter);
        
        lastSelectedItemPosition = 0;
    }

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		
		if (DataModel.getInstance().getCityList().get(position).getDays() != null) {
			showCityForecast(position);
		} else {
			lastSelectedItemPosition = position;
			showDialog(DIALOG_UPDATE_NEEDED);
		}
	}

	@Override
	protected void onPause() {
		// TODO Save list item position here so that it will be the same when returning to this activity.
		// Perhaps it's worth using SharedPreferences for this purpose.
		// See http://code.google.com/android/reference/android/app/Activity.html for some sample.
		super.onPause();
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.clear();
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		
		int citiesNum = DataModel.getInstance().getCityList().size();
		if (citiesNum == 0) {
			menu.removeItem(R.id.update_city);
			menu.removeItem(R.id.update_all_cities);
			menu.removeItem(R.id.city_management);
		} else if (citiesNum == 1) {
			menu.removeItem(R.id.add_city);	// Remove from main menu, but it's available under City man. submenu
			menu.removeItem(R.id.update_all_cities);
		} else {
			menu.removeItem(R.id.add_city);	// Remove from main menu, but it's available under City man. submenu
		}

		return true;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		boolean result;
		switch (item.getItemId()) {
			case R.id.add_city:
			case R.id.add_city_submenu:{
				Intent i = new Intent(this, CitySelectionActivity.class);
				startActivityForResult(i, CitySelectionActivity.GET_CITY);
				result = true;
			}
			break;
				
			case R.id.remove_city: {
				// TODO Handle when lastSelectedItemPosition == -1 ==> no city is selected
				// A dialog could be shown asking the user to select first
				DataModel model = DataModel.getInstance();
				City city = model.getCityList().get(lastSelectedItemPosition);
				
				try {
					model.removeCity(city);
				} catch (Exception e) {
					// TODO Handle when removeCity throws exception
				}
				
				setListAdapter(getListAdapter());	// // update model
				result = true;
			}
			break;
				
			case R.id.city_management: {
				lastSelectedItemPosition = getSelectedItemPosition();
				result = true;
			}
			break;
			
			case R.id.update_city: {
				lastSelectedItemPosition = getSelectedItemPosition();	// needs to be up-to-date for next call
				performCityUpdate(false);	// update selected city only
				result = true;
			}
			break;
				
			case R.id.update_all_cities: {
				performCityUpdate(true);	// update ALL cities
				result = true;
			}
			break;
				
			case R.id.settings: {
				Intent i = new Intent(this, SettingsActivity.class);
				startActivity(i);
				result = true;
			}
			break;
				
			default:
				result = super.onMenuItemSelected(featureId, item); 
		}
		return result;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
			case CitySelectionActivity.GET_CITY:
				// TODO Check if some values are uninitialized
				if (data != null) {	// might be null if we pressed Back in City Selection view
					City city = new City();
					Bundle bundle = data.getExtras();
					city.setCountryName(bundle.getString(CitySelectionActivity.BUNDLE_PARAM_COUNTRY));
					city.setName(bundle.getString(CitySelectionActivity.BUNDLE_PARAM_CITY));
					city.setId(bundle.getString(CitySelectionActivity.BUNDLE_PARAM_CITY_ID));
					
					try {
						DataModel.getInstance().addCity(city);
					} catch (Exception e) {
						// TODO Handle when addCity throws exception
					}
					
					setListAdapter(getListAdapter());	// update model
				}
				break;
				
			default:
				break;
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog result = null;
		switch (id) {
			case DIALOG_PROGRESSBAR: {
				ProgressDialog dialog = new ProgressDialog(this);
				dialog.setTitle(R.string.dialog_update_title);
				dialog.setMessage(getString(R.string.dialog_update_message));
				dialog.setIndeterminate(true);
				dialog.setCancelable(false);
				result = dialog;
			}
			break;
				
			case DIALOG_UPDATE_NEEDED: {
				AlertDialog dialog = new AlertDialog.Builder(this)
					.setIcon(R.drawable.alert_dialog_icon)
					.setTitle(R.string.dialog_title_update_needed)
					.setMessage(R.string.dialog_citylist_update_needed)
					.setPositiveButton(R.string.dialog_query_yes, new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// Update city
							CityListActivity.this.performCityUpdate(false);
							CityListActivity.this.openAfterUpdate = true;	// enable opening forecast details
																			// after update completes
						}
					})
					.setNegativeButton(R.string.dialog_query_no, new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// No need to do anything, just let the control be back in City List view
						}
					})
					.create();
				result = dialog;
			}
			break;
		}
		return result;
	}
	
	private void performCityUpdate(boolean updateAllCities) {
		ArrayList<City> citiesToBeUpdated = null;
		if (!updateAllCities) {
			citiesToBeUpdated = new ArrayList<City>();
			citiesToBeUpdated.add(DataModel.getInstance().getCityList().get(lastSelectedItemPosition));
		}
		
		Thread networker = new Thread(new Networker(this, updateHandler, citiesToBeUpdated));
		networker.start();
		showDialog(DIALOG_PROGRESSBAR);
	}
	
	private void showCityForecast(int position) {
		Intent i = new Intent(this, ForecastListActivity.class);
		i.putExtra(CLICK_POSITION, position);
		startActivity(i);
	}
}